import Vue from 'vue'
import { getChild } from '../_tool/utils'
import Item from './swiper-item'

export default {
  name: 'Swiper',
  props: {
    currentIndex: { type: Number, default: 0 },
    mode: { type: String, default: 'horizontal' },//
    dots: Boolean,
    autoplay: Boolean,
    loop: { type: Boolean, default: false },
    delay: { type: Number, default: 3500 },
    touch: { type: Boolean, default: true },
  },
  data() {
    return {
      factor: 1,
      startY: 0, startX: 0, //起始点
      tempX: 0, tempY: 0,
      moveY: 0, moveX: 0, //移动位置 
      width: 0, height: 0,
      defaultIndex: this.currentIndex,
      time: this.defaultIndex > 0 ? 0 : 300,
      autoTimer: null,
      childs: []
    }
  },
  watch: {
    currentIndex(index) {
      // if (index < 0) index = 0;
      // if (index > this.childs.length) index = this.childs.length - 1
      if (this.defaultIndex != index) {
        this.defaultIndex = index
        this.changeMove()
      }
    },
  },
  beforeDestroy() {
    clearInterval(this.autoTimer)
    clearInterval(this.resetTimer)
    window.removeEventListener('resize', this.resize)
  },
  mounted() {
    this.updateChild()
    // this.resize()
    window.addEventListener('resize', this.resize)
    this.setSize()
    this.changeMove()
    if (this.autoplay) this.autoPlay()
  },

  render() {
    let props = {
      class: 'k-swiper-container',
      on: {
        touchstart: this.start,
        touchend: this.end,
        touchmove: this.move
      },
      style: {
        transform: `translateX(${this.moveX}px) translateY(${this.moveY}px)`,
        // transform: `translate3d(${this.moveX}px,${this.moveY}px,0)`,
        transition: `transform ${this.time}ms`
      },
    }
    let { $slots, childs } = this
    // console.log(childs)
    // console.log(child)
    let child = childs.length > 0 ? childs : getChild($slots.default)
    let count = child.length - (this.loop ? 2 : 0)
    // console.log(count)
    const dotsNode = this.getDots(count)
    return (
      <div class={`k-swiper ${this.mode == 'vertical' ? 'k-swiper-vertical' : ''}`} ref="swiper">
        <div {...props}>
          {child}
        </div>
        {dotsNode}
      </div>
    )
  },
  updated() {
    if (this.loop && this.$slots.default && this.$slots.default.length != this.childs.length - 2) {
      this.updateChild()
    }
  },
  methods: {
    getDots(count) {
      if (!this.dots || count <= 1) return null
      let dots = []
      for (let i = 0; i < count; i++) {
        dots.push(<span class={`k-swiper-dot ${i == this.defaultIndex ? 'k-swiper-dot-actived' : ''}`}></span>)
      }
      return <div class="k-swiper-dots">{dots}</div>
    },
    setSize() {
      let { width, height } = getComputedStyle(this.$refs.swiper)
      this.height = parseFloat(height)
      this.width = parseFloat(width)
    },
    updateChild() {
      if (!this.loop || this.childs.length == 1) return;
      // this.childs = null
      let child = getChild(this.$slots.default)
      // console.log('update')
      if (child.length > 1 && this.loop) {
        // console.log(this.childs[0])
        let first = this.copyChild(child[0])
        let last = this.copyChild(child[child.length - 1])

        child.unshift(last)
        child.push(first)

      }
      if (this.defaultIndex > child.length - 2) {
        this.defaultIndex = child.length - 2
      }
      if (child.length == 1) this.defaultIndex = -1
      // console.log(this.defaultIndex)
      this.childs = child
      this.changeMove()
    },
    copyChild(child) {
      if (!child) return null
      // debugger
      let { attrs, on } = child.data
      let slot = child.componentOptions.children
      // let { $attrs, $listeners, $slots } = child.componentInstance
      // console.log($attrs, $listeners, $slots)
      let props = {
        attrs,
        on
      }
      let copyNode = <Item {...props}>{slot}</Item>
      return copyNode
    },
    changeMove() {
      let index = this.defaultIndex + (this.loop ? 1 : 0)
      if (this.mode == 'horizontal') {
        this.moveX = index * this.width * -1
      } else {
        this.moveY = index * this.height * -1
      }
    },
    autoPlay() {
      clearInterval(this.autoTimer)
      this.autoTimer = setInterval(() => {
        let index = this.defaultIndex
        this.time = 300
        if (this.childs.length == 1) {
          return;
        }
        if (this.loop) {
          if (index == this.childs.length - 1 - 2) {
            this.defaultIndex = 0
            this.mode == 'horizontal' ?
              this.moveX = -1 * this.width * (this.childs.length - 1) :
              this.moveY = -1 * this.height * (this.childs.length - 1)

            clearInterval(this.resetTimer)

            this.resetTimer = setTimeout(e => {
              this.time = 0
              this.mode == 'horizontal' ?
                this.moveX = -1 * this.width :
                this.moveY = -1 * this.height
            }, 300)
            return;
          } else {
            index += 1
          }
        } else {
          if (index == this.$slots.default.length - 1) {
            index = 0
          } else {
            index++
          }
        }
        this.defaultIndex = index
        this.changeMove()
      }, this.delay);
    },
    resize() {
      // return;
      this.setSize()
      // if (this.childs == 1) return;
      let { height, width, defaultIndex, mode } = this
      this.time = 0
      let count = this.childs.length
      if (count == 1) {
        this.vertical && (this.moveY = 0);
        this.horizontal && (this.moveX = 0)
        return;
      }
      if (mode == 'vertical') {
        this.childs.map(c =>
          c.elm.style.height = height + 'px'
        )
        this.moveY = defaultIndex * height * -1
      } else {
        this.childs.map(c =>
          c.elm.style.width = width + 'px'
        )
        this.moveX = defaultIndex * width * -1
      }
    },
    end(e) {
      if (!this.touch) return

      if (this.autoplay) {
        this.autoPlay()
      }
      this.$emit('touchend', e)
      let { pageX, pageY } = e.changedTouches[0]
      let { startX, startY, defaultIndex, mode, width, height, loop } = this
      let moveX = Math.abs(startX - pageX)
      let moveY = Math.abs(startY - pageY)
      this.time = 300
      this.factor = 1
      let count = (loop ? this.childs : getChild(this.$slots.default)).length
      let isFirst = defaultIndex == 0
      let isLast = (defaultIndex == (count - 1))

      let moveRight = pageX > startX
      let moveLeft = pageX < startX

      let moveUp = pageY < startY
      let moveDown = pageY > startY

      // console.log(isLast, count, defaultIndex)

      let vertical = mode == 'vertical'
      let horizontal = mode == 'horizontal'
      //如果已经移动了，就不能触发点击事件
      if (((~~moveX != 0 && horizontal) || (~~moveY != 0 && vertical)) && e.cancelable) { //
        // console.log(mode,moveX)
        e.preventDefault()
        e.stopPropagation()
      }

      let timeIn = (Date.now() - this.timestamp) < 500
      if (count == 1) {
        vertical && (this.moveY = 0);
        horizontal && (this.moveX = 0)
        return;
      }
      if (horizontal && ((isFirst && moveRight && !loop) || (isLast && moveLeft && !loop))) {
        this.moveX = defaultIndex * width * -1
        return;
      }
      if (vertical && ((isFirst && moveDown && !loop) || (isLast && moveUp && !loop))) {
        this.moveY = defaultIndex * height * -1
        return;
      }
      let canChangeX = (timeIn && ~~moveX != 0) || (moveX > this.width / 2)
      let canChangeY = (timeIn && ~~moveY != 0) || (moveY > this.height / 2)
      if (horizontal && moveX > moveY && canChangeX) {
        moveRight && this.defaultIndex--
        moveLeft && this.defaultIndex++
      } else if (vertical && moveY > moveX && canChangeY) {
        moveDown && this.defaultIndex--
        moveUp && this.defaultIndex++
      }

      // if (!this.loop) {
      // if (defaultIndex < 0)
      //   this.defaultIndex = 0
      // if (defaultIndex > count - 1)
      //   this.defaultIndex = count - 1
      // }
      let index = this.defaultIndex
      // console.log(index)
      if (loop) {
        if (index < 0) {
          index = 0
          this.defaultIndex = count - 2 - 1
        } else if (index > count - 2 - 1) {
          index += 1
          this.defaultIndex = 0
        } else index += 1
      }
      // if (index > count - 2) index = 0
      if (horizontal) {
        this.moveX = index * width * -1
        if (defaultIndex != index) {
          this.$emit('tabChange', index)
        }
      } else if (vertical) {
        this.moveY = index * height * -1
        if (defaultIndex != index) {
          this.$emit('tabChange', index)
        }
      }
      this.startX = 0
      this.startY = 0

    },
    start(e) {
      if (!this.touch) return
      this.$emit('touchstart', e)
      this.timestamp = Date.now();
      this.time = 0;

      this.$emit('touchstart', e)
      let { pageX, pageY } = e.changedTouches[0]

      this.startX = pageX
      this.startY = pageY
      this.tempX = pageX
      this.tempY = pageY
      if (this.loop) {
        if (this.defaultIndex == 0) {
          this.mode == 'horizontal' ?
            this.moveX = -1 * this.width :
            this.moveY = -1 * this.height
        }
        if (this.defaultIndex == this.childs.length - 1 - 2) {
          this.mode == 'horizontal' ?
            this.moveX = -1 * this.width * (this.childs.length - 2) :
            this.moveY = -1 * this.height * (this.childs.length - 2)
        }
      }
      if (this.autoplay) {
        clearInterval(this.autoTimer)
        clearInterval(this.resetTimer)
      }
    },
    move(e) {
      if (!this.touch) return

      let { pageX, pageY } = e.changedTouches[0]
      let { startX, startY, mode, defaultIndex, loop } = this
      let moveX = Math.abs(startX - pageX)
      let moveY = Math.abs(startY - pageY)

      let count = (loop ? this.childs : getChild(this.$slots.default)).length
      let isFirst = defaultIndex == 0
      let isLast = (defaultIndex == (count - 1))
      // console.log(count, isLast, defaultIndex)
      // debugger
      let moveRight = pageX > startX
      let moveLeft = pageX < startX

      let moveUp = pageY < startY
      let moveDown = pageY > startY

      let vertical = mode == 'vertical'
      let horizontal = mode == 'horizontal'

      this.$emit('touchmove', e, {
        isLeft: moveX > moveY && moveLeft,
        isRight: moveX > moveY && moveRight,
        isUp: moveY > moveX && moveUp,
        isDown: moveY > moveX && moveDown,
      })

      if (horizontal && moveX > moveY) {
        if ((isFirst && moveRight && !loop) || (isLast && moveLeft && !loop) || count == 1) {
          if (this.factor > 0.2)
            this.factor -= 0.05
        } else {
          this.factor = 1
        }
        this.moveX += (pageX - this.tempX) * this.factor
        this.tempX = pageX
        if (e.cancelable) {
          e.preventDefault()
          e.stopPropagation()
        }
      } else if (vertical && moveY > moveX) {
        if ((isFirst && moveDown && !loop) || (isLast && moveUp && !loop) || count == 1) {
          if (this.factor > 0.2)
            this.factor -= 0.05
        } else {
          this.factor = 1
        }
        this.moveY += (pageY - this.tempY) * this.factor
        this.tempY = pageY
        if (e.cancelable) {
          e.preventDefault()
          e.stopPropagation()
        }
      }
      this.time = 0;
    }
  },
}